#include <stdio.h>

// 1.memcpy
// void * memcpy ( void * destination, const void * source, size_t num );
void* my_memcpy(void *dest, const void *src, size_t num)
{
    if(dest == NULL || src == NULL) {
        return NULL;
    }
    char *dest_ch = (char*)dest;
    char *src_ch = (char*)src;
    while(num--) {
        *dest_ch = *src_ch;
        dest_ch++;
        src_ch++;
    }
    
    return dest;
}

void* my_memmove(void *dest, const void *src, size_t num)
{
    if(dest == NULL || src == NULL) {
        return NULL;
    }

    char *dest_ch = (char*)dest;
    const char *src_ch = (const char*)src;

    // 情况1：目标地址在源地址之后，并且有重叠，此时从后向前拷贝
    if(src_ch < dest_ch && src_ch + num >= dest_ch) {
        dest_ch += num;
        src_ch += num;
        while(num--) {
            *(--dest_ch) = *(--src_ch);
            //src_ch--;
            //dest_ch--;
            //*dest_ch = *src_ch;
        }
    }else {
        // 情况2：无重叠/目标地址在源地址之前，都是用从前向后拷贝
        while(num--) {
            *dest_ch++ = *src_ch++;
            //*dest_ch = *src_ch;
            //src_ch++;
            //dest_ch++;
        }
    }

    return dest;
}


char *my_strstr(const char *str1, const char *str2)
{
    // 如果str2为空串，返回str1的起始地址
    if(*str2 == '\0') return (char*)str1;

    char *start = (char*)str1; // 开始匹配的位置
    char *s1 = NULL, *s2 = NULL;             // 用来遍历主串和子串
    
    while(*start != '\0') {
        s1 = start;
        s2 = (char*)str2;

        // s1和s2都没有结束，并且两者相等
        while(*s1 != '\0' && *s2 != '\0' && *s1 == *s2) {
            s1++;
            s2++;
        }

        // 匹配结束，判断原因
        if(*s2 == '\0') {
            // s2结束，匹配成功
            return start;
        }else if(*s1 == '\0') {
            // s1结束，匹配失败
            break;
        }
        start++;
    }
    return NULL;
}


size_t my_strlen1(const char *str)
{
    size_t length = 0;
    while(*str != '\0') {
        length++;
        str++;
    }
    return length;
}

size_t my_strlen2(const char *str)
{
    if(*str == '\0') return 0;

    return 1 + my_strlen2(str+1);
}

size_t my_strlen3(const char *str)
{
    const char *begin = str;
    const char *end = NULL;
    while(*str++ != '\0') ;
    end = str - 1;
    return end - begin;
}

char *my_strcpy(char *dest, const char *src)
{
    char *orignal = dest;
    while(*dest++ = *src++) ;
    return orignal;
}

int my_strcmp(const char *str1, const char *str2)
{
    while(*str1 == *str2) {
        if(*str1 == '\0') return 0;
        str1++;
        str2++;
    }
    return *str1 - *str2;
}


char *my_strcat(char *dest, const char *src)
{
    if(dest == NULL || src == NULL) return NULL;
    char *orignal = dest;
    
    // 找到dest的结尾
    while(*dest) dest++;
    while(*dest++ = *src++) ;
    return orignal;
}

//int main()
//{
//    printf("默认最大对齐数: %d 字节\n", __BIGGEST_ALIGNMENT__);
//    return 0;
//}

//struct S1
//{
//    char c1;
//    int i;
//    char c2;
//};
//int main()
//{
//    printf("%d\n", sizeof(struct S1));
//    
//    return 0;
//}

#include <stdio.h>
//结构体嵌套
 
struct S3
{
	double d;
	char c;
	int i;
};
 
struct S4
{
	char c1;
	struct S3 s3;
	double d;
};
 
//int main()
//{
//	printf("%zd\n", sizeof(struct S3));
//	printf("%zd\n", sizeof(struct S4));
//	return 0;
//}

//#include <stdio.h>
//
//int main() {
//    // __BIGGEST_ALIGNMENT__ 是GCC预定义宏，表示最大默认对齐字节数
//    printf("GCC默认最大对齐字节数: %d\n", __BIGGEST_ALIGNMENT__);
//    return 0;
//}


//struct empty
//{};
//
//int main()
//{
//    printf("%zd\n", sizeof(struct empty));
//    return 0;
//}


//利用#pragma修改默认对齐数
 
//#include <stdio.h>
//#pragma pack(1)//设置默认对⻬数为1 
//struct S
//{
//	char c1;
//	int i;
//	char c2;
//};
//#pragma pack()//取消设置的对⻬数，还原为默认 
// 
//int main()
//{
//	//输出的结果是什么？ 
//	printf("%d\n", sizeof(struct S));
//	return 0;
//}


//struct seg
//{
//    char _a:2;
//    char _b:3;
//    char _c:5;
//    char _d:8;   
//};
//
//int main()
//{
//    printf("%ld\n", sizeof(struct seg));
//    return 0;
//}

//union judge
//{
//    int i;
//    char c;
//};
//
//int main()
//{
//    union judge j;
//    j.i = 1;
//
//    // j.c访问低地址
//    if(j.c == 1) {
//        printf("小端\n");
//    }else {
//        printf("大端\n");
//    }
//    return 0;
//}


//int main()
//{
//    int i = 1;
//    char *ch = (char*)&i;
//    if(*ch == 1) {
//        printf("小端\n");
//    }else {
//        printf("大端\n");
//    }
//    return 0;
//}


#include <stdio.h>
 
int main()
{
    int n = 9;
    float* pFloat = (float*)&n;
    
    printf("n的值为：%d\n", n);
    printf("*pFloat的值为：%f\n", *pFloat);
    
    *pFloat = 9.0;
    
    printf("num的值为：%d\n", n);
    printf("*pFloat的值为：%f\n", *pFloat);
    return 0;
}